/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package saltocaballo.Interfaces;

import de.javasoft.plaf.synthetica.SyntheticaBlackMoonLookAndFeel;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;
import saltocaballo.comunes.Configuracion;
import saltocaballo.entidades.Casilla;
import saltocaballo.comunes.constantes;
import saltocaballo.comunes.iniciarSistema;
import saltocaballo.comunes.logger;
import saltocaballo.entidades.Tablero;
import saltocaballo.expertos.*;

/**
 *
 * @author Martinoxs
 */
public class principal extends javax.swing.JFrame {

    private iniciarSistema iniSis;
    private Configuracion conf;
    private Casilla panelActual;
    private movimientosCaballo movimientos;
    private Tablero tablero;
    private logger log;
    private Backtracking backtracking;
    private arcoConsistencia ac3;
    private SinMetodo ninguno;
    private List<String> listaObstaculos;

    public Configuracion getConf() {
        return conf;
    }
    
    /**
     * Creates new form principal
     */
    public principal() {
        initComponents();
        iniSis = new iniciarSistema();
        conf = iniSis.getConf();
        movimientos = new movimientosCaballo();
        tablero = new Tablero(panelCasillas);
        log = new logger();
        backtracking = new Backtracking();
        ac3 = new arcoConsistencia();
        ninguno = new SinMetodo();
        listaObstaculos = new ArrayList<String>();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jSeparator1 = new javax.swing.JSeparator();
        jLabel3 = new javax.swing.JLabel();
        panelCasillas = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        txtAncho = new javax.swing.JFormattedTextField();
        jLabel7 = new javax.swing.JLabel();
        txtAlto = new javax.swing.JFormattedTextField();
        btnCrearTablero = new javax.swing.JButton();
        btnSalir = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JSeparator();
        jLabel8 = new javax.swing.JLabel();
        txtCantObstaculos = new javax.swing.JFormattedTextField();
        btnGenerarObstaculos = new javax.swing.JButton();
        jSeparator3 = new javax.swing.JSeparator();
        jLabel9 = new javax.swing.JLabel();
        comboMetodo = new javax.swing.JComboBox();
        jLabel10 = new javax.swing.JLabel();
        comboHeuristica = new javax.swing.JComboBox();
        btnResolver = new javax.swing.JButton();
        btnRepetirObstaculos = new javax.swing.JButton();
        btnManual = new javax.swing.JToggleButton();
        chkLOG = new javax.swing.JCheckBox();
        chkConsola = new javax.swing.JCheckBox();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        menuAyuda = new javax.swing.JMenu();
        menuComojugar = new javax.swing.JMenuItem();
        menuAcercaDe = new javax.swing.JMenuItem();
        menuSalir = new javax.swing.JMenuItem();
        menuConfigurar = new javax.swing.JMenu();
        Configurar = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Juego Salto de Caballo - Inteligencia Artificial - Universidad Tecnológica Nacional");

        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        jLabel1.setText("Inteligencia Artificial 2012");

        jLabel2.setText("Proyecto Salto de Caballo");

        jLabel3.setText("Ingrese cantidad de casillas:");

        panelCasillas.setBackground(new java.awt.Color(204, 204, 204));
        panelCasillas.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        panelCasillas.setFocusable(false);
        panelCasillas.setName("panelCasillas");
        panelCasillas.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                panelCasillasMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                panelCasillasMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                panelCasillasMouseExited(evt);
            }
        });

        javax.swing.GroupLayout panelCasillasLayout = new javax.swing.GroupLayout(panelCasillas);
        panelCasillas.setLayout(panelCasillasLayout);
        panelCasillasLayout.setHorizontalGroup(
            panelCasillasLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 534, Short.MAX_VALUE)
        );
        panelCasillasLayout.setVerticalGroup(
            panelCasillasLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );

        jLabel4.setText("Alto:");

        jLabel5.setText("Ancho:");

        jLabel6.setText("mín 3 - max 50");

        txtAncho.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0"))));

        jLabel7.setText("mín 3 - máx 50");

        txtAlto.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0"))));

        btnCrearTablero.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/tablero.png"))); // NOI18N
        btnCrearTablero.setMnemonic('r');
        btnCrearTablero.setText("Crear Tablero");
        btnCrearTablero.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCrearTableroActionPerformed(evt);
            }
        });

        btnSalir.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/exit.png"))); // NOI18N
        btnSalir.setMnemonic('a');
        btnSalir.setText("Salir");
        btnSalir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSalirActionPerformed(evt);
            }
        });

        jLabel8.setText("Cantidad de Obstáculos:");

        txtCantObstaculos.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0"))));

        btnGenerarObstaculos.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/obstaculos.png"))); // NOI18N
        btnGenerarObstaculos.setText("Generar Obstáculos");
        btnGenerarObstaculos.setEnabled(false);
        btnGenerarObstaculos.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnGenerarObstaculosActionPerformed(evt);
            }
        });

        jLabel9.setText("Resolver por:");

        comboMetodo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Backtracking", "AC-3", "Ninguno" }));

        jLabel10.setText("Heurística:");

        comboHeuristica.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "MVR", "Grado", "Ninguna" }));

        btnResolver.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/cerebro.png"))); // NOI18N
        btnResolver.setText("Resolver");
        btnResolver.setToolTipText("Busca una solución al tablero");
        btnResolver.setEnabled(false);
        btnResolver.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnResolverActionPerformed(evt);
            }
        });

        btnRepetirObstaculos.setText("Repetir Obstáculos");
        btnRepetirObstaculos.setToolTipText("Repite los obstáculos del último problema");
        btnRepetirObstaculos.setEnabled(false);
        btnRepetirObstaculos.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRepetirObstaculosActionPerformed(evt);
            }
        });

        btnManual.setText("Manual");
        btnManual.setToolTipText("Permite colocar un obstáculo en una casilla deseada");
        btnManual.setEnabled(false);
        btnManual.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnManualActionPerformed(evt);
            }
        });

        chkLOG.setText("Habilitar LOG");
        chkLOG.setToolTipText("Genera un archivo con el paso a paso de la ejecución");
        chkLOG.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkLOGActionPerformed(evt);
            }
        });

        chkConsola.setText("Habilitar Consola");
        chkConsola.setToolTipText("Permite ver el paso a paso de la ejecución por consola");
        chkConsola.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkConsolaActionPerformed(evt);
            }
        });

        jMenu1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/caballoSmall.png"))); // NOI18N
        jMenu1.setMnemonic('s');
        jMenu1.setText("Sistema");

        menuAyuda.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/ayuda.png"))); // NOI18N
        menuAyuda.setMnemonic('a');
        menuAyuda.setText("Ayuda");

        menuComojugar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/ayuda.png"))); // NOI18N
        menuComojugar.setMnemonic('c');
        menuComojugar.setText("Cómo Jugar?");
        menuComojugar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuComojugarActionPerformed(evt);
            }
        });
        menuAyuda.add(menuComojugar);

        menuAcercaDe.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/question.png"))); // NOI18N
        menuAcercaDe.setMnemonic('e');
        menuAcercaDe.setText("Acerca de...");
        menuAcercaDe.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuAcercaDeActionPerformed(evt);
            }
        });
        menuAyuda.add(menuAcercaDe);

        jMenu1.add(menuAyuda);

        menuSalir.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/exit.png"))); // NOI18N
        menuSalir.setMnemonic('l');
        menuSalir.setText("Salir");
        menuSalir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuSalirActionPerformed(evt);
            }
        });
        jMenu1.add(menuSalir);

        jMenuBar1.add(jMenu1);

        menuConfigurar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/config.png"))); // NOI18N
        menuConfigurar.setMnemonic('c');
        menuConfigurar.setText("Configurar");
        menuConfigurar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuConfigurarActionPerformed(evt);
            }
        });

        Configurar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iconos/config.png"))); // NOI18N
        Configurar.setMnemonic('n');
        Configurar.setText("Configurar");
        Configurar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ConfigurarActionPerformed(evt);
            }
        });
        menuConfigurar.add(Configurar);

        jMenuBar1.add(menuConfigurar);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSeparator1)
                    .addComponent(btnGenerarObstaculos, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(comboMetodo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(comboHeuristica, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btnResolver, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btnSalir, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jSeparator2)
                    .addComponent(btnCrearTablero, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel8)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txtCantObstaculos))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btnRepetirObstaculos, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnManual, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE))
                    .addComponent(jSeparator3)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2)
                            .addComponent(jLabel3)
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel4)
                                    .addComponent(jLabel5))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addComponent(txtAncho, javax.swing.GroupLayout.DEFAULT_SIZE, 58, Short.MAX_VALUE)
                                    .addComponent(txtAlto))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel6)
                                    .addComponent(jLabel7)))
                            .addComponent(jLabel10))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jLabel9)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(chkLOG, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(chkConsola, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addComponent(panelCasillas, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel4)
                            .addComponent(jLabel6)
                            .addComponent(txtAncho, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel5)
                            .addComponent(jLabel7)
                            .addComponent(txtAlto, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(btnCrearTablero)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(1, 1, 1)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel8)
                            .addComponent(txtCantObstaculos, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnGenerarObstaculos)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(btnRepetirObstaculos)
                            .addComponent(btnManual))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(chkConsola)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(chkLOG)
                            .addComponent(jLabel9))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(comboMetodo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel10)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(comboHeuristica, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnResolver)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnSalir)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addComponent(panelCasillas, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void menuComojugarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuComojugarActionPerformed
        JOptionPane.showMessageDialog(this, "Tochi acá tenés que redactar la ayuda de cómo jugar!!");
    }//GEN-LAST:event_menuComojugarActionPerformed

    private void menuSalirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuSalirActionPerformed
        salirSistema();
    }//GEN-LAST:event_menuSalirActionPerformed

    private void btnSalirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSalirActionPerformed
        salirSistema();
    }//GEN-LAST:event_btnSalirActionPerformed

    private void menuAcercaDeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuAcercaDeActionPerformed
        JOptionPane.showMessageDialog(this, "Tochi acá van los créditos nuestros!");
    }//GEN-LAST:event_menuAcercaDeActionPerformed

    private void menuConfigurarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuConfigurarActionPerformed
        System.out.println("Acción!!!");
    }//GEN-LAST:event_menuConfigurarActionPerformed

    private void ConfigurarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ConfigurarActionPerformed
        uiConfiguracion uiConf = new uiConfiguracion("Configuración", false, false, false, false, this);
        añadirJFrameAUIPpal(uiConf);
    }//GEN-LAST:event_ConfigurarActionPerformed

    private void btnCrearTableroActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCrearTableroActionPerformed
        crearTablero();
    }//GEN-LAST:event_btnCrearTableroActionPerformed

    private void panelCasillasMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_panelCasillasMouseClicked
        
    }//GEN-LAST:event_panelCasillasMouseClicked

    private void btnGenerarObstaculosActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGenerarObstaculosActionPerformed
        // TODO add your handling code here:
        
        int cantCasillas = getColumnasTablero() * getFilasTablero();
        int cantObstaculos = 0;
        Random rnd = new Random();
        
        if (!txtCantObstaculos.getText().isEmpty()){
            
            cantObstaculos = Integer.parseInt(txtCantObstaculos.getText());
            listaObstaculos.clear();
            btnRepetirObstaculos.setEnabled(true);
            
            if((cantCasillas/cantObstaculos) < 2){
                JOptionPane.showMessageDialog(this, "La cantidad de obstáculos no puede ser mayor a la mitad de la cantidad de casillas");
            } else {
                int MaxFila = getFilasTablero() - 1; 
                int MaxColumna = getColumnasTablero() - 1;
                int filaRnd;
                int colRnd;
                String coordCasillaRnd;
                String imagen;
                boolean obstaculoGenerado;

                for (int i = 0; i < cantObstaculos; i++){
                    obstaculoGenerado = false;
                    while(!obstaculoGenerado){
                        filaRnd = (int)(rnd.nextDouble() * MaxFila);
                        colRnd = (int)(rnd.nextDouble() * MaxColumna);
                        coordCasillaRnd = String.valueOf(filaRnd) + ";" + String.valueOf(colRnd);

                        for (Casilla p: getCasillas()){
                            if (p.getCoordenada().equals(coordCasillaRnd) && !p.tieneObstaculo() && !p.tieneCaballo()){
                                
                                listaObstaculos.add(p.getCoordenada());
                                
                                if (p.getBackground().equals(Color.BLACK)){
                                    imagen = constantes.cajaNegro;
                                } else {
                                    imagen = constantes.cajaBlanco;
                                }
                                try{
                                    Image img = ImageIO.read(this.getClass().getResource(imagen));
                                    p.setImagen(img);
                                } catch (Exception ex){
                                    System.out.println("Error al setear imagen caja");
                                }
                                obstaculoGenerado = true;
                                p.setObstaculo(true);
                                p.repaint();
                            }
                        }
                    }
                }
                
                btnGenerarObstaculos.setEnabled(false);
            }
        }
    }//GEN-LAST:event_btnGenerarObstaculosActionPerformed

    private void btnResolverActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnResolverActionPerformed
        //Resolver Tablero
        botonesObstaculos(false);
        btnResolver.setEnabled(false);
        btnResolver.setText("Resolviendo....");
        
        String busqueda = comboMetodo.getSelectedItem().toString();
        String metodo = comboHeuristica.getSelectedItem().toString();
        String rdo = "";
        long tiempoIni = System.currentTimeMillis();
        long tiempoFin = 0l;
        int iteraciones = 0;
        Runtime run = Runtime.getRuntime();
        long memoriaInicial = run.totalMemory() - run.freeMemory();
        long memoriaFinal = 0l;
        NumberFormat formateador = NumberFormat.getNumberInstance();
        formateador.setMaximumFractionDigits(2);
        
        this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
        
        //Copiar Tablero para poder comparar
        Tablero nuevoTablero = new Tablero(panelCasillas);
        
        JPanel nuevoPanel = new JPanel();
        Casilla casilla;

        //Copio casillas
        for(Component c: panelCasillas.getComponents()){
            casilla = new Casilla();
            if (c.getClass().equals(Casilla.class)){
                Casilla cas = (Casilla) c;
                casilla.setName(cas.getName());
                casilla.setCoordenada(cas.getCoordenada());
                if (cas.tieneObstaculo()) casilla.setObstaculo(true);
                nuevoPanel.add(casilla);
            }
        }
        
        nuevoTablero.setTableroCopia(nuevoPanel);
        nuevoTablero.setCasillaInicio(tablero.getCasillaInicio());
        
        nuevoPanel.repaint();
        nuevoPanel.updateUI();
        
        if (busqueda.equals(constantes.backtracking)){
            rdo = backtracking.resolver(nuevoTablero,metodo, log);
            if (rdo.startsWith("El Tablero")){
                JOptionPane.showMessageDialog(this, rdo);
            } else {
                if (rdo.startsWith("No se")){
                    JOptionPane.showMessageDialog(this, rdo);
                } else {
                    tableroResultado uiTab = new tableroResultado(rdo, nuevoTablero.getCantFilas(), nuevoTablero.getCantColumnas(), nuevoTablero.getCasillaInicio().getCoordenada());
                    uiTab.setVisible(true);
                    String[] datos = rdo.split("Tablero Resuelto en: ");
                    String[] it = datos[1].split(" ");
                    iteraciones = Integer.parseInt(it[0]);
                    tiempoFin = System.currentTimeMillis() - tiempoIni;
                    memoriaFinal = run.totalMemory() - run.freeMemory();
                }
            }            
        } else if (busqueda.equals(constantes.arcoConsistencia)){
            rdo = ac3.resolver(nuevoTablero, metodo, log);
            if (rdo.startsWith("No se")){
                JOptionPane.showMessageDialog(this, rdo);
            } else {
                tableroResultado uiTab = new tableroResultado(rdo, nuevoTablero.getCantFilas(), nuevoTablero.getCantColumnas(), nuevoTablero.getCasillaInicio().getCoordenada());
                uiTab.setVisible(true);
                String[] datos = rdo.split("Tablero Resuelto en: ");
                String[] it = datos[1].split(" ");
                iteraciones = Integer.parseInt(it[0]);
                tiempoFin = System.currentTimeMillis() - tiempoIni;
                memoriaFinal = run.totalMemory() - run.freeMemory();
            }        
        } else {
            rdo = ninguno.resolver(nuevoTablero, metodo, log);
            if (rdo.startsWith("El Tablero")){
                JOptionPane.showMessageDialog(this, rdo);
            } else {
                tableroResultado uiTab = new tableroResultado(rdo, nuevoTablero.getCantFilas(), nuevoTablero.getCantColumnas(), nuevoTablero.getCasillaInicio().getCoordenada());
                uiTab.setVisible(true);
                String[] datos = rdo.split("Tablero Resuelto en: ");
                String[] it = datos[1].split(" ");
                iteraciones = Integer.parseInt(it[0]);
                tiempoFin = System.currentTimeMillis() - tiempoIni;
                memoriaFinal = run.totalMemory() - run.freeMemory();
            }
        }
        
        log.escribirLinea("---------------------------------------------------------");
        log.escribirLinea("---------------------------------------------------------");
        log.escribirLinea("    ESTADÍSTICAS DE LA BÚSQUEDA:");
        log.escribirLinea("    * Cantidad de iteraciones: " + iteraciones);
        log.escribirLinea("    * Tiempo transcurrido: " + formateador.format(tiempoFin) + " milisegundos.");
        log.escribirLinea("    * Memoria usada: " + formateador.format((memoriaFinal - memoriaInicial) / 1024) + " KB");
        log.imprimirFichero();
        
        btnResolver.setText("Resolver");
        this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    }//GEN-LAST:event_btnResolverActionPerformed

    private void btnRepetirObstaculosActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRepetirObstaculosActionPerformed
        
        String imagen;
        
        for(String cas: listaObstaculos){
            for (Casilla p: getCasillas()){
                if (p.getCoordenada().equals(cas)){
                    if (p.getBackground().equals(Color.BLACK)){
                        imagen = constantes.cajaNegro;
                    } else {
                        imagen = constantes.cajaBlanco;
                    }
                    try{
                        Image img = ImageIO.read(this.getClass().getResource(imagen));
                        p.setImagen(img);
                    } catch (Exception ex){
                        System.out.println("Error al setear imagen caja");
                    }
                    
                    p.setObstaculo(true);
                    p.repaint();
                }
            }
        }
        
    }//GEN-LAST:event_btnRepetirObstaculosActionPerformed

    private void btnManualActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnManualActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_btnManualActionPerformed

    private void chkLOGActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkLOGActionPerformed
        if (chkLOG.isSelected()){
            conf.setLog(true);
        } else {
            conf.setLog(false);
        }
    }//GEN-LAST:event_chkLOGActionPerformed

    private void panelCasillasMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_panelCasillasMouseEntered
        this.setCursor(new Cursor(Cursor.HAND_CURSOR));
    }//GEN-LAST:event_panelCasillasMouseEntered

    private void panelCasillasMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_panelCasillasMouseExited
        this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    }//GEN-LAST:event_panelCasillasMouseExited

    private void chkConsolaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkConsolaActionPerformed
        if (chkConsola.isSelected()){
            conf.setlogConsola(true);
        } else {
            conf.setlogConsola(false);
        }
    }//GEN-LAST:event_chkConsolaActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                try {
                    UIManager.setLookAndFeel(new SyntheticaBlackMoonLookAndFeel());
                } catch (ParseException ex) {
                    if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                    }
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(principal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(principal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(principal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(principal.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                final JFrame uiApp = new principal();
                BufferedImage image = null;
                try {
                    image = ImageIO.read(uiApp.getClass().getResource("/iconos/logo.png"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                uiApp.setIconImage(image);
                uiApp.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem Configurar;
    private javax.swing.JButton btnCrearTablero;
    private javax.swing.JButton btnGenerarObstaculos;
    private javax.swing.JToggleButton btnManual;
    private javax.swing.JButton btnRepetirObstaculos;
    private javax.swing.JButton btnResolver;
    private javax.swing.JButton btnSalir;
    private javax.swing.JCheckBox chkConsola;
    private javax.swing.JCheckBox chkLOG;
    private javax.swing.JComboBox comboHeuristica;
    private javax.swing.JComboBox comboMetodo;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JMenuItem menuAcercaDe;
    private javax.swing.JMenu menuAyuda;
    private javax.swing.JMenuItem menuComojugar;
    private javax.swing.JMenu menuConfigurar;
    private javax.swing.JMenuItem menuSalir;
    private javax.swing.JPanel panelCasillas;
    private javax.swing.JFormattedTextField txtAlto;
    private javax.swing.JFormattedTextField txtAncho;
    private javax.swing.JFormattedTextField txtCantObstaculos;
    // End of variables declaration//GEN-END:variables

    private void añadirJFrameAUIPpal(JInternalFrame ui) {
        ui.setVisible(true);
        ui.setBounds((panelCasillas.getWidth() / 2) - (ui.getPreferredSize().width / 2), (panelCasillas.getHeight() / 2) - (ui.getPreferredSize().height / 2), ui.getPreferredSize().width, ui.getPreferredSize().height);
        panelCasillas.add(ui);
        ui.toFront();
    }

    private void salirSistema(){
        int opcion = JOptionPane.showConfirmDialog(this, "¿Seguro desea salir?");
        if (JOptionPane.OK_OPTION == opcion) {
            this.dispose();
        }        
    }

    private void generarTablero(int cantVert, int cantHoriz) {
        int contadorI = 0;
        int contadorJ = 0;
        
        Color colorActual = constantes.colorInicial;
        String nombreImagen = "";
        String color;
        
        tablero.setCantColumnas(cantVert);
        tablero.setCantFilas(cantHoriz);
        conf.setTablero(tablero);
        
        for (int i = 0; i < cantVert; i++){
            for (int j = 0; j < cantHoriz; j++){
                final Casilla panel = new Casilla();
                
                if(colorActual.equals(Color.BLACK)){
                    color = "-N";
                } else {
                    color = "-B";
                }
                
                //agrego propiedades
                panel.setName(String.valueOf(j).concat(";").concat(String.valueOf(i)).concat(color));
                panel.setCoordenada(String.valueOf(j).concat(";").concat(String.valueOf(i)));
                panel.setPreferredSize(new Dimension(conf.getTamanioCasilla(),conf.getTamanioCasilla())); 
                panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
                panel.setBounds(contadorI, contadorJ, conf.getTamanioCasilla(), conf.getTamanioCasilla());
                contadorJ += conf.getTamanioCasilla();
                
                //agrego eventos
                panel.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mousePressed(MouseEvent e) {
                        String ruta = "";                        
                        Image imagen;
                        
                        if (btnManual.isSelected()){
                            if (!panel.tieneCaballo()){
                                if (panel.getBackground().equals(Color.BLACK)){
                                    ruta = constantes.cajaNegro;
                                } else {
                                    ruta = constantes.cajaBlanco;
                                }

                                try{
                                    imagen = ImageIO.read(this.getClass().getResource(ruta));
                                    panel.setImagen(imagen);
                                    panel.setObstaculo(true);
                                    listaObstaculos.add(panel.getCoordenada());
                                } catch (Exception ex){
                                    System.out.println("Error al setear imagen caja");
                                }
                            }
                        } else {
                            if (movimientos.esCasillaValida(panel,panelActual,getTamañoTablero())){
                                try{
                                    imagen = ImageIO.read(this.getClass().getResource(constantes.caballo));
                                    panel.setImagen(imagen);
                                    btnRepetirObstaculos.setEnabled(true);
                                } catch (Exception ex){
                                    System.out.println("Error al setear imagen caballo");
                                }
                                limpiarPanelAnterior();                        
                                panel.repaint();
                                panel.setTieneCaballo(true);
                                if (tablero.getCasillaInicio() == null){ 
                                    tablero.setCasillaInicio(panel);
                                    btnResolver.setEnabled(true);
                                    tablero.setTableroCopia(clonarPanel());
                                }
                                panelActual = panel;
                                if(movimientos.getMovimientosValidos(panel.getCoordenada(), tablero, tablero.getPanel()).isEmpty() && !tablero.tableroResuelto(tablero.getPanel())){
                                    int opcion = JOptionPane.showConfirmDialog(panelCasillas, "Perdió!! No existen movimientos posibles!\n¿Desea jugar de nuevo?");
                                    if (JOptionPane.OK_OPTION == opcion) {
                                        crearTablero();
                                    } else if(JOptionPane.NO_OPTION == opcion){
                                        panelCasillas.setEnabled(false);
                                    }
                                } else {
                                    if (tablero.tableroResuelto(tablero.getPanel())){
                                        int opcion = JOptionPane.showConfirmDialog(panelCasillas, "Ganó!! Desea jugar de nuevo?");
                                    if (JOptionPane.OK_OPTION == opcion) {
                                        crearTablero();
                                    } else if(JOptionPane.NO_OPTION == opcion){
                                        panelCasillas.setEnabled(false);
                                    }
                                    }
                                }
                            } else {
                                System.out.println("Casilla no válida");
                            }
                        }
                    }
                    
                    @Override
                    public void mouseEntered(MouseEvent e) {
                        panel.setCursor(new Cursor(Cursor.HAND_CURSOR));
                    }
                    
                    @Override
                    public void mouseExited(MouseEvent e) {
                        panel.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                    }

                    private void limpiarPanelAnterior() {
                        if (panelActual != null){                            
                            String nombreImagen;
                            
                            if(panelActual.getName().contains("-N")){
                                nombreImagen = constantes.cruzNegra;
                            } else {
                                nombreImagen = constantes.cruzBlanca;
                            }
                            
                            try{
                                Image imagen = ImageIO.read(this.getClass().getResource(nombreImagen));
                                panelActual.setImagen(imagen);
                            } catch (Exception ex){
                                System.out.println("Error al setear imagen");
                            }
                            
                            panelActual.setVisitada(true);
                            for(MouseListener m: panelActual.getMouseListeners()){
                                panelActual.removeMouseListener(m);
                            }
                        } 
                    }
                });
                
                if(colorActual.equals(Color.BLACK)){
                    nombreImagen = constantes.casillaNegra;
                    panel.setBackground(Color.BLACK);
                } else {
                    nombreImagen = constantes.casillaBlanca;
                    panel.setBackground(Color.WHITE);
                }
                
                try{
                    Image imagen = ImageIO.read(this.getClass().getResource(nombreImagen));
                    panel.setImagen(imagen);
                } catch (Exception ex){
                    System.out.println("Error al setear imagen");
                }
                
                colorActual = getColorAlterno(colorActual);
                
                panel.setVisible(true);
                panel.repaint();
                
                panelCasillas.add(panel);
                panelCasillas.updateUI();
            }
            contadorI += conf.getTamanioCasilla();
            if (cantHoriz%2 == 0){
                colorActual = getColorAlterno(colorActual);
            }
            contadorJ = 0;
        }
    }
    
    public JPanel clonarPanel() {
        JPanel nuevoPanel = new JPanel();
        Casilla casilla;

        //Copio casillas
        for(Component c: panelCasillas.getComponents()){
            casilla = new Casilla();
            if (c.getClass().equals(Casilla.class)){
                Casilla cas = (Casilla) c;
                casilla.setName(cas.getName());
                casilla.setCoordenada(cas.getCoordenada());
                if (cas.tieneObstaculo()) casilla.setObstaculo(true);
                nuevoPanel.add(casilla);
            }
        }

        return nuevoPanel;
    }

    private Color getColorAlterno(Color color) {
        if (color.equals(Color.WHITE)){
            return Color.BLACK;
        } else {
            return Color.WHITE;
        }
    }

    private void limpiarTablero() {
        panelCasillas.removeAll();
        panelActual = null;
        tablero = new Tablero(panelCasillas);
    }
    
    public List<Casilla> getCasillas(){
        List<Casilla> listaCasillas = new ArrayList<Casilla>();
        for(Component c: panelCasillas.getComponents()){
            if(c.getClass().equals(Casilla.class)){
                Casilla p = (Casilla) c;
                listaCasillas.add(p);
            }
        }
        return listaCasillas;
    }
    
    public String getTamañoTablero(){
        return txtAlto.getText() + "x" + txtAncho.getText();
    }
    
    public int getFilasTablero(){
        return Integer.parseInt(txtAncho.getText());
    }
    
    public int getColumnasTablero(){
        return Integer.parseInt(txtAlto.getText());
    }
    
    private void crearTablero(){
        panelCasillas.setEnabled(true);
        if (!txtAlto.getText().isEmpty() && !txtAncho.getText().isEmpty()){
            if ((Integer.parseInt(txtAlto.getText()) >= 3)
                    && (Integer.parseInt(txtAlto.getText()) <= 50)
                    && (Integer.parseInt(txtAncho.getText()) >= 3)
                    && (Integer.parseInt(txtAncho.getText()) <= 50)){
                if (!(Integer.parseInt(txtAlto.getText()) == 3 && (Integer.parseInt(txtAncho.getText()) == 3))){
                    botonesObstaculos(true);
                    limpiarTablero();
                    generarTablero(Integer.parseInt(txtAlto.getText()),Integer.parseInt(txtAncho.getText()));
                } else {
                    JOptionPane.showMessageDialog(this, "El tablero mínimo es de 3x4 o 4x3");
                }
            } else {
                JOptionPane.showMessageDialog(this, "Debe ingresar ambos valores dentro de los límites");
            }
        } else {
            JOptionPane.showMessageDialog(this, "Debe ingresar ambos valores");
        }        
    }

    private void botonesObstaculos(boolean estado) {
        btnGenerarObstaculos.setEnabled(estado);
        btnManual.setEnabled(estado);
        btnRepetirObstaculos.setEnabled(estado);
    }
}
